#include "State.h"

extern "C"
{
#include "lua.h"

#include "lauxlib.h"

#include "lualib.h"
}

class LuaScriptState : public State
{
    const static int N_METHODS = 9;

    const static char *METHOD_TABLE[];

private:
    lua_State *m_context;

    bool m_methodDefinitions[N_METHODS];

public:

    LuaScriptState();


    LuaScriptState(EngineCore *engine, const std::string& script);


    ~LuaScriptState();


    /**
     * Calls the Create function residing in the script.
     */

    virtual void Create();


    /**
     * Updates the State by calling the correspondive method in the lua script.
     * The standard Update must occurr first (Entity, Rendering and Physics managers).
     *
     * @param delta: time elapsed since last call.
     */

    virtual void Update(unsigned delta);

    /**
     * Receives a message from an entity.
     *
     */

    virtual void OnEntityMessage(EntitySystem::Entity* sender, const std::string& msg);


    /**
     * Pushes keyboard events to the Entities. Then it forwards keyboard event to the script.
     *
     * @param event: a keyboard event occurred.
     */

    virtual void OnKeyboardEvent(KeyboardEvent& event);


    /**
     * Calls regular State Update. Then forwards the mouse event to the script.
     * 
     * @param event: a mouse event occurred. 
     */

    virtual void OnMouseEvent(MouseEvent& event);


    /**
     * Called when an action is performed on a gui component belonging to this State.
     *
     * @param sender: gui component that triggered the action.
     */

    virtual void ActionPerformed(gui::Component *sender);


    /**
     * Calls the pause function implemented in script.
     */

    virtual void Pause();


    /**
     * Calls the resume function implemented in script.
     */

    virtual void Resume();


    /**
     * Calls the cleanup function implemented in script.
     */
    virtual void Cleanup();


private:

    /**
     * Checks which methods of State are implemented in the script.
     */

    void CheckMethodDefinitions();


    /**
     * Prints an error occurred when executing a script function. 
     *
     * @param methodIndex: index (in METHOD_TABLE) of the function that failed to execute.
     * @param errorCode: error code returned by lua.
     */

    void PrintExecError(int methodIndex, int errorCode);
};